package com.szh.publisher.controller;


import com.szh.common.constant.MQConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Random;
import java.util.UUID;

/**
 * 
 *基于 spring-boot-starter-amqp 通过 rabbitTemplate发送消息
 * 
 */
@RestController
@RequestMapping
@Slf4j
public class V1 {
    @Resource
    RabbitTemplate rabbitTemplate;
    

    /**模式1： p-q-c 模式 */
    @GetMapping("/sendMsg")
    public void sendMsg() {
        int nextInt = new Random().nextInt(1000);
        String msg = "hello -->" + nextInt;
        
        rabbitTemplate.convertAndSend("",MQConstant.HELLO_JAVA_QUEUE,msg);
        log.info("MQ-简单模式-发送休息：{}", msg);
    }

    // todo 测试发现。若是向不存在的队列发生消息。则会丢失消息
    /**测试 生产者 向不存在的队列发生消息* */
    @GetMapping("/sendToNoExistQueueMsg")
    public void sendToNoExistQueueMsg() {
        int nextInt = new Random().nextInt(1000);
        String msg = "hello -->" + nextInt;

        rabbitTemplate.convertAndSend("",MQConstant.TEST_NO_EXIST_QUEUE,msg);
        log.info("测试 生产者 向不存在的队列发生消息*：{}", msg);
    }

    /**
     *
     */
    @GetMapping("/sendMsgAndConfirmCallback")
    public void sendMsgAndConfirmCallback() {
        String msg = "hello java ConfirmCallback";

        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(UUID.randomUUID().toString());
        correlationData.getFuture().addCallback(result -> {
            // 判断结果
            if (result.isAck()) {
                // ACK
                log.debug("消息成功投递到交换机！消息ID: {}", correlationData.getId());
            } else {
                // NACK
                log.error("消息投递到交换机失败！消息ID：{}", correlationData.getId());
                // 重发消息
            }
        }, ex -> {
            // 记录日志
            log.error("消息发送失败！", ex);
            // 重发消息
        });
        // 发送消息
        /*
        * todo 失败情况一：没有到达交换机。比如：交换机写的是错误的
        *  todo 失败情况二：到达交换机了，但是没有到队列。比如：路由key写错了
        * */
        rabbitTemplate.convertAndSend(MQConstant.DIRECT_EXCHANGE_NAME, MQConstant.DIRECT_RED_ROUTE_KEY, msg, correlationData);
    }

    @GetMapping("/sendMsg50")
    public void sendMsg50() {

        String msg = "hello -->";

        for (int i = 0; i < 50; i++) {
            rabbitTemplate.convertAndSend(MQConstant.DIRECT_EXCHANGE_NAME, MQConstant.DIRECT_RED_ROUTE_KEY, msg + i);
        }
        log.info("50条 ---发送成功");
    }

    @GetMapping("/sendMsgObj")
    public void sendMsgObj() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("role", "六月");
        map.put("122", 122);
        rabbitTemplate.convertAndSend(MQConstant.DIRECT_EXCHANGE_NAME, MQConstant.DIRECT_RED_ROUTE_KEY,  map);
        log.info("50条 ---发送成功");
    }

    /**
     * 延时队列测试
     *
     * @throws UnsupportedEncodingException
     */
    @GetMapping("send/delayQueueTest")
    public void delayQueueTest() throws UnsupportedEncodingException {


        String msg = "延时消息+==";
        for (int i = 0; i < 50; i++) {
            int nextInt = new Random().nextInt(20);
            rabbitTemplate.convertAndSend(MQConstant.DELAY_EXCHANGE_NAME, MQConstant.DELAY_ROUTE_KEY, msg + nextInt, correlationData -> {
                correlationData.getMessageProperties().setDelay(nextInt * 1000);
                return correlationData;
            });
        }
        log.error("发送成功");
    }
}
